home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
SimHector
/
cpu
/
ControlUnit.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
8KB
|
270 lines
///////////////////////////////////////////////////////////////////////////////
//
// ControlUnit.cxx - Control Unit for the Hector 1600 CPU
// (behavioral level)
//
// By: Bradford W. Mott
// December 4,1993
//
///////////////////////////////////////////////////////////////////////////////
#include "ControlUnit.hxx"
#include "Tools.hxx"
///////////////////////////////////////////////////////////////////////////////
// Execute the next instruction
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::ExecuteInstruction(String& trace_record,
int trace_flag)
{
const char *error_message;
// Reset the Data Path Signals
data_path.ResetSignals();
// Added the Instruction Address field to the trace_record if tracing
if(trace_flag)
{
trace_record+="{InstructionAddress {";
trace_record+=IntToString(data_path.register_set.GetRegister(PC), 4);
trace_record+="}}";
}
// Fetch the next instruction and put it in IR
data_path.a_sel(PC);
data_path.mar_sel(A_BUS);
data_path.mar_latch();
data_path.mar_out_en();
data_path.ir_latch();
data_path.alu_fn(INC_A_NCC);
data_path.alu_gt();
data_path.wrt_a();
if(( error_message = data_path.Clock() ) != (void*)0)
return(error_message);
error_message=DecodeAndExecute(trace_flag);
// If there wasn't an error then add the mnemonic to the trace_record
if((error_message == (void*)0) && trace_flag)
{
mnemonic+="}}";
trace_record+=" ";
trace_record+=mnemonic;
}
return(error_message);
}
///////////////////////////////////////////////////////////////////////////////
// Decode the instruction in the IR register and execute it
///////////////////////////////////////////////////////////////////////////////
const char* ControlUnit::DecodeAndExecute(int trace_flag)
{
const char* error_message;
int dm = (data_path.ir & 0x0300) >> 8; // Destination Mode field
int sm = (data_path.ir & 0x0c00) >> 10; // Source Mode field
// Setup the mnemonic trace entry
if(trace_flag)
mnemonic="{Mnemonic {";
switch ((data_path.ir & 0xf000) >> 12)
{
case 0: // ADD
if(trace_flag) mnemonic+="ADD ";
error_message=ExecuteGroup1(trace_flag);
break;
case 1: // ADDC
if(trace_flag) mnemonic+="ADDC ";
error_message=ExecuteGroup1(trace_flag);
break;
case 2: // SUB
if(trace_flag) mnemonic+="SUB ";
error_message=ExecuteGroup1(trace_flag);
break;
case 3: // AND
if(trace_flag) mnemonic+="AND ";
error_message=ExecuteGroup1(trace_flag);
break;
case 4: // SUBC
if(trace_flag) mnemonic+="SUBC ";
error_message=ExecuteGroup1(trace_flag);
break;
case 5: // OR
if(trace_flag) mnemonic+="OR ";
error_message=ExecuteGroup1(trace_flag);
break;
case 6: // XOR
if(trace_flag) mnemonic+="XOR ";
error_message=ExecuteGroup1(trace_flag);
break;
case 7: // Stop
error_message="STOP instruction";
break;
case 8: // NOT, NEG, INC, DEC
switch (dm)
{
case 0: // NOT
if(trace_flag) mnemonic+="NOT ";
error_message=ExecuteGroup2(trace_flag);
break;
case 1: // NEG
if(trace_flag) mnemonic+="NEG ";
error_message=ExecuteGroup2(trace_flag);
break;
case 2: // INC
if(trace_flag) mnemonic+="INC ";
error_message=ExecuteGroup2(trace_flag);
break;
case 3: // DEC
if(trace_flag) mnemonic+="DEC ";
error_message=ExecuteGroup2(trace_flag);
break;
}
break;
case 9: // SHL, ROL, SHR, ROR
switch (dm)
{
case 0: // SHL
if(trace_flag) mnemonic+="SHL ";
error_message=ExecuteGroup2(trace_flag);
break;
case 1: // ROL
if(trace_flag) mnemonic+="ROL ";
error_message=ExecuteGroup2(trace_flag);
break;
case 2: // SHR
if(trace_flag) mnemonic+="SHR ";
error_message=ExecuteGroup2(trace_flag);
break;
case 3: // ROR
if(trace_flag) mnemonic+="ROR ";
error_message=ExecuteGroup2(trace_flag);
break;
}
break;
case 10: // CMP
if(trace_flag) mnemonic+="CMP ";
error_message=ExecuteGroup3(trace_flag);
break;
case 11: // BTST
if(trace_flag) mnemonic+="BTST ";
error_message=ExecuteGroup3(trace_flag);
break;
case 12: // BRA, JSR, SWAP, CLR
switch (dm)
{
case 0: // BRA
if(trace_flag) mnemonic+="BRA ";
error_message=ExecuteBRA(trace_flag);
break;
case 1: // JSR
if(trace_flag) mnemonic+="JSR ";
error_message=ExecuteJSR(trace_flag);
break;
case 2: // SWAP
if(trace_flag) mnemonic+="SWAP ";
error_message=ExecuteSWAP(trace_flag);
break;
case 3: // CLR
if(trace_flag) mnemonic+="CLR ";
error_message=ExecuteCLR(trace_flag);
break;
}
break;
case 13: // MOVE
if(trace_flag) mnemonic+="MOVE ";
error_message=ExecuteMOVE(trace_flag);
break;
case 14: // TEST, STF, LDF, PUSH
switch (dm)
{
case 0: // TEST
if(trace_flag) mnemonic+="TEST ";
error_message=ExecuteTEST(trace_flag);
break;
case 1: // STF
if(trace_flag) mnemonic+="STF ";
error_message=ExecuteSTF(trace_flag);
break;
case 2: // LDF
if(trace_flag) mnemonic+="LDF ";
error_message=ExecuteLDF(trace_flag);
break;
case 3: // PUSH
if(trace_flag) mnemonic+="PUSH ";
error_message=ExecutePUSH(trace_flag);
break;
}
break;
case 15: // SEC, CLC, SEI, CLI, RTI, SWI, EXCH, SRCH
switch (sm)
{
case 0: // SEC, CLC, SEI, CLI
switch (dm)
{
case 0: // SEC
if(trace_flag) mnemonic+="SEC ";
error_message=ExecuteSEC(trace_flag);
break;
case 1: // CLC
if(trace_flag) mnemonic+="CLC ";
error_message=ExecuteCLC(trace_flag);
break;
case 2: // SEI
if(trace_flag) mnemonic+="SEI ";
error_message=ExecuteSEI(trace_flag);
break;
case 3: // CLI
if(trace_flag) mnemonic+="CLI ";
error_message=ExecuteCLI(trace_flag);
break;
}
break;
case 1: // RTI, SWI, EXCH, SRCH
switch (dm)
{
case 0: // RTI
if(trace_flag) mnemonic+="RTI ";
error_message=ExecuteRTI(trace_flag);
break;
case 1: // SWI
if(trace_flag) mnemonic+="SWI ";
error_message=ExecuteSWI(trace_flag);
break;
case 2: // EXCH
if(trace_flag) mnemonic+="EXCH ";
error_message=ExecuteEXCH(trace_flag);
break;
case 3: // SRCH
if(trace_flag) mnemonic+="SRCH ";
error_message=ExecuteSRCH(trace_flag);
break;
}
break;
}
break;
default:
error_message="Illegal Opcode";
break;
}
return(error_message);
}